package itsm.isperp.module.utils;

import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.data.domain.PageResponse;
import itsm.isperp.framework.domain.IBean;
import itsm.isperp.framework.utils.DateUtils;
import itsm.isperp.framework.utils.FileUtils;
import itsm.isperp.framework.web.response.JqGridResponse;
import itsm.isperp.module.repository.solr.BaseSolrRepository;
import itsm.isperp.module.service.knowledge.KngKnowledgeItemService;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;
import java.util.Map;

import me.chanjar.weixin.common.util.StringUtils;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
import org.apache.solr.common.util.NamedList;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.result.HighlightEntry;
import org.springframework.data.solr.core.query.result.HighlightPage;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * 
 * solr工具类
 * 
 * @author lizx
 * @date 2014-4-28
 * @since 1.0
 * 
 */
public final class SolrUtils {

	/**
	 * 为列表字段高亮
	 * 
	 * @param page
	 * @return
	 */
	public static final <T extends IBean> PageResponse<T> genericHighlightPageResponse(
			final HighlightPage<T> page) {

		List<HighlightEntry<T>> hList = page.getHighlighted();
		List<T> content = page.getContent();
		for (int i = 0, size = hList.size(); i < size; i++) {
			HighlightEntry<T> he = hList.get(i);
			T entity = content.get(i);

			List<HighlightEntry.Highlight> hhList = he.getHighlights();
			for (int j = 0, js = hhList.size(); j < js; j++) {
				HighlightEntry.Highlight hg = hhList.get(j);
				try {
					Field field = entity.getClass().getDeclaredField(
							hg.getField().getName());
					field.setAccessible(true);
					field.set(entity, hg.getSnipplets().get(0).toString());
				} catch (Exception e) {
				}
			}

		}

		return new JqGridResponse<T>(page);
	}

	/**
	 * 根据名称获取到solr导入到sql语句
	 * 
	 * @param name
	 * @return
	 * @throws DocumentException
	 */
	public static final String getQueryDtoByName(final String name)
			throws DocumentException {

		String xmlFile = ContextHolder.getApplicationClassPath()
				+ "solr/isperp/conf/db-data-config.xml";

		File file = new File(xmlFile);

		SAXReader reader = new SAXReader();
		Document document = reader.read(file);
		Element node = (Element) document
				.selectSingleNode("/dataConfig/document/entity[@name='" + name
						+ "']");
		return node.attribute("query").getText();
	}

	private static SolrQuery createSolrQuery(String id, boolean delta,
			String itemType) {

		SolrQuery query = new SolrQuery();
		// 指定RequestHandler，默认使用/select
		query.setRequestHandler("/dataimport");

		String command = delta ? "delta-import" : "full-import";
		String clean = delta ? "false" : "true";
		String optimize = delta ? "false" : "true";
		if (StringUtils.isNotEmpty(id)) {
			query.setParam("pk", "id");
			query.setParam("itemid", id);
		}
		query.setParam("itemtype", itemType);
		query.setParam("command", command).setParam("clean", clean)
				.setParam("commit", "true").setParam("optimize", optimize)
				.setParam("synchronous", true);
		return query;
	}

	/**
	 * 根据id实时索引
	 * 
	 * @param id
	 * @throws DocumentException
	 */
	public static final void saveIndex(final String id)
			throws DocumentException {

		String sql = "SELECT ID,'knowledge' AS st  FROM kng_knowledge_item "
				+ " UNION ALL SELECT ID,'incident' AS st FROM icd_incident "
				+ " UNION ALL SELECT ID,'servicecatalog' AS st FROM src_service "
				+ " UNION ALL SELECT ID,'user' AS st FROM app_user WHERE ID='"
				+ id + "'  ";

		JdbcTemplate jt = ContextHolder.getSpringBean(JdbcTemplate.class);
		Map<String, Object> map = jt.queryForMap(sql);
		saveIndex(map.get("st").toString(), id);
	}

	/**
	 * 实时的创建索引
	 * 
	 * @param type
	 * @param businessKey
	 * @throws DocumentException
	 */
	public static void saveIndex(final String type, final String businessKey)
			throws DocumentException {
		String mtype = type.trim().toLowerCase();
		BaseSolrRepository<?> rep = null;
		switch (mtype) {
		case "knowledge":
			rep = ContextHolder.getSpringBean("solrKngKnowledgeItem");
			break;
		case "knowledge2":
			rep = ContextHolder.getSpringBean("solrKngKnowledgeItem2");
			break;
		case "incident":
			rep = ContextHolder.getSpringBean("solrIcdIncident");
			break;
		case "servicecatalog":
			rep = ContextHolder.getSpringBean("solrSrcService");
			break;
		case "user":
			rep = ContextHolder.getSpringBean("solrAppUser");
			break;
		}

		if (rep != null) {
			rep.saveIndex(businessKey);
		}
	}

	public static void rebuildServicecatalogIndex() throws SolrServerException,
			IOException {
		SolrTemplate st = ContextHolder.getSpringBean(SolrTemplate.class);

		SolrQuery query = createSolrQuery(null, false, "servicecatalog");

		st.getSolrServer().query(query);
	}

	public static void rebuildIncidentIndex(String id, boolean delta)
			throws SolrServerException, IOException {
		SolrTemplate st = ContextHolder.getSpringBean(SolrTemplate.class);

		SolrQuery query = createSolrQuery(id, delta, "icdIncident");

		st.getSolrServer().query(query);
	}

	public static void rebuildKnowledgeIndex(String id)
			throws SolrServerException, IOException {
		rebuildKnowledgeIndex(id, false);
	}

	public static void rebuildKnowledgeIndex(String id, boolean delta)
			throws SolrServerException, IOException {

		SolrTemplate st = ContextHolder.getSpringBean(SolrTemplate.class);

		SolrQuery query = createSolrQuery(id, delta, "kngKnowledgeItem");
		SolrServer solr = st.getSolrServer();
		solr.query(query);

		KngKnowledgeItemService kngKnowledgeItemService = ContextHolder
				.getSpringBean("kngKnowledgeItemService");
		List<Map<String, Object>> fs = kngKnowledgeItemService
				.findKnowLedgeFile(id);
		rebuildKnowledgeFileIndex(fs, solr);
	}

	public static void rebuildIndex() throws SolrServerException, IOException {
		rebuildIndex(true);
	}

	/**
	 * 
	 * @param delta
	 *            是否增量
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public static void rebuildIndex(boolean delta) throws SolrServerException,
			IOException {

		SolrTemplate st = ContextHolder.getSpringBean(SolrTemplate.class);

		SolrQuery query = new SolrQuery();
		// 指定RequestHandler，默认使用/select
		query.setRequestHandler("/dataimport");

		String command = delta ? "delta-import" : "full-import";
		String clean = delta ? "false" : "true";
		String optimize = delta ? "false" : "true";

		query.setParam("command", command).setParam("clean", clean)
				.setParam("commit", "true").setParam("optimize", optimize)
				.setParam("synchronous", true);

		st.getSolrServer().query(query);

		// rebuildKnowledgeFileIndex();
	}

	public static void rebuildKnowledgeFileIndex(List<Map<String, Object>> fs)
			throws IOException, SolrServerException {
		SolrTemplate st = ContextHolder.getSpringBean(SolrTemplate.class);

		SolrServer solr = st.getSolrServer();
		rebuildKnowledgeFileIndex(fs, solr);
	}

	public static void rebuildKnowledgeFileIndex(String kngItemId)
			throws IOException, SolrServerException {
		SolrTemplate st = ContextHolder.getSpringBean(SolrTemplate.class);

		SolrServer solr = st.getSolrServer();
		KngKnowledgeItemService kngKnowledgeItemService = ContextHolder
				.getSpringBean("kngKnowledgeItemService");
		List<Map<String, Object>> fs = kngKnowledgeItemService
				.findKnowLedgeFile(kngItemId);
		rebuildKnowledgeFileIndex(fs, solr);
	}

	public static void rebuildKnowledgeFileIndex(List<Map<String, Object>> fs,
			SolrServer solr) throws IOException, SolrServerException {

		for (Map<String, Object> f : fs) {

			ContentStreamUpdateRequest up = new ContentStreamUpdateRequest(
					"/update/extract");
			String contentType = (String) f.get("content_type");
			String fp = FileUtils.getFileRealPath((String) f.get("path"));
			File fi = new File(fp);
			if (!fi.exists()) {
				continue;
			}
			up.addFile(fi, contentType);
			up.setParam("literal.id", (String) f.get("id"));
			up.setParam("literal.classType", "SolrKngKnowledgeDTO");
			up.setParam("literal.sourceId", (String) f.get("source_id"));
			up.setParam("literal.title", (String) f.get("name"));
			String s = DateUtils.formatDateTime((Date) f.get("modify_date"));
			up.setParam("literal.publishDate", s);
			
			up.setParam("literal.categoryId", (String) f.get("category_id"));

			up.setParam("literal.categoryPath", (String) f.get("category_path"));
			up.setParam("literal.categoryName", (String) f.get("category_name"));
			up.setParam("literal.status", (String) f.get("status"));
			up.setParam("uprefix", "attr_");
			up.setParam("fmap.content", "contents");

			up.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);
			NamedList<Object> result = solr.request(up);

		}

	}
}
